local map = vim.api.nvim_set_keymap
local opt = { noremap = true, silent = true }

local M = {}

require("core.plugin")

-- require("noice").setup({
-- 	lsp = {
-- 		-- override markdown rendering so that **cmp** and other plugins use **Treesitter**
-- 		override = {
-- 			["vim.lsp.util.convert_input_to_markdown_lines"] = true,
-- 			["vim.lsp.util.stylize_markdown"] = true,
-- 			["cmp.entry.get_documentation"] = true,
-- 		},
-- 	},
-- 	-- you can enable a preset for easier configuration
-- 	presets = {
-- 		bottom_search = true, -- use a classic bottom cmdline for search
-- 		command_palette = true, -- position the cmdline and popupmenu together
-- 		long_message_to_split = true, -- long messages will be sent to a split
-- 		inc_rename = false, -- enables an input dialog for inc-rename.nvim
-- 		lsp_doc_border = false, -- add a border to hover docs and signature help
-- 	},
-- })

require("nvim-window").setup({
	-- The characters available for hinting windows.
	chars = {
		"a",
		"b",
		"c",
		"d",
		"e",
		"f",
		"g",
		"h",
		"i",
		"j",
		"k",
		"l",
		"m",
		"n",
		"o",
		"p",
		"q",
		"r",
		"s",
		"t",
		"u",
		"v",
		"w",
		"x",
		"y",
		"z",
	},
	-- A group to use for overwriting the Normal highlight group in the floating
	-- window. This can be used to change the background color.
	normal_hl = "Normal",
	-- The highlight group to apply to the line that contains the hint characters.
	-- This is used to make them stand out more.
	hint_hl = "Bold",
	-- The border style to use for the floating window.
	border = "single",
})

M.window = {
	n = {
		["wh"] = { "<C-w>h", "select left" },
		["wj"] = { "<C-w>j", "select down" },
		["wk"] = { "<C-w>k", "select up" },
		["wl"] = { "<C-w>l", "select right" },
		["wc"] = { "<C-w>c", "close current" },
		["wo"] = { "<C-w>o", "close other" },
		["sv"] = { ":vsp<CR>", "horizontal" },
		["sh"] = { ":sp<CR>", "vertical" },
		["ww"] = { "<C-w><C-w>", "select float" },
		["<LEADER>w"] = { ":lua require('nvim-window').pick()<CR>", "pick window" },
	},
}

M.general = {
	n = {
		["<ESC>"] = { "<cmd> noh <CR>", "no highlight" },
		["<LEADER>m"] = { "m8", "temporary mark" },
		["<LEADER><BACKSPACE>"] = { "`8", "back temporary mark" },
	},
	x = {
		["p"] = { 'p:let @+=@0<CR>:let @"=@0<CR>', "dont copy replaced text" },
	},
}

-- catppuccin
local ok, catppuccin = pcall(require, "catppuccin")
if ok then
	-- latte, frappe, macchiato, mocha
	vim.g.catppuccin_flavour = "mocha"
	catppuccin.setup({
		integrations = {
			treesitter = true,
			gitsigns = true,
			leap = true,
			telescope = true,
			cmp = true,
			lsp_saga = true,
			barbar = true,
		},
	})
	vim.cmd([[colorscheme catppuccin]])
end
-- vim.cmd([[colorscheme gruvbox]])
-- vim.cmd([[set background=light]])

-- nvimtree
require("core.custom.nvimtree-config")
map("n", "<LEADER>e", "<CMD>NvimTreeOpen<CR>", opt)

-- telescope
local trouble = require("trouble.providers.telescope")
require("telescope").setup({
	defaults = {
		mappings = {
			-- i = { ["<c-t>"] = trouble.open_with_trouble },
			-- n = { ["<c-t>"] = trouble.open_with_trouble },
		},
	},
})
require("core.custom.telescope-custom")
require("telescope").load_extension("dap")
M.telescope = {
	n = {
		["<LEADER>fw"] = {
			"<CMD>lua require('telescope.builtin').live_grep({glob_pattern={'!vendor', '!node_modules'}})<CR>",
			"Search keywork in your working directory",
		},
		["<LEADER>ff"] = { "<CMD>Telescope find_files<CR>", "find file" },
		["<LEADER><LEADER>"] = { "<CMD>Telescope command_center<CR>", "command center" },
	},
}

-- todo-comment
M.todo = {
	n = {
		["<LEADER>td"] = { "<CMD>TodoTelescope<CR>", "todo telescope" },
	},
}

-- which key
require("core.custom.which-key-config")

-- barbar
require("core.custom.barbar-config")
M.buffer = {
	n = {
		["<C-h>"] = { "<Cmd>BufferPrevious<CR>", "previous buffer" },
		["<C-l>"] = { "<Cmd>BufferNext<CR>", "next buffer" },
		["<C-w>"] = { "<Cmd>BufferClose<CR>", "close current buffer" },
	},
	o = {
		{ "<CMD>BufferCloseAllButCurrent<CR>", "co close other buffer" },
		{ "<CMD>BufferCloseBuffersRight<CR>", "cr close right buffer" },
		{ "<CMD>BufferCloseBuffersLeft<CR>", "cl close left buffer" },
	},
}

-- lualine
require("core.custom.lualine-config")

-- gitsign
local gs = require("gitsigns")
gs.setup({
	attach_to_untracked = true,
	current_line_blame = true, -- Toggle with `:Gitsigns toggle_current_line_blame`
	current_line_blame_opts = {
		virt_text = true,
		virt_text_pos = "eol", -- 'eol' | 'overlay' | 'right_align'
		delay = 300,
		ignore_whitespace = false,
	},
})
M.gitsigns = {
	o = {
		{ "<CMD>lua require('gitsigns').diffthis('~')<CR>", "git diff this" },
	},
	n = {
		-- Navigation through hunks
		["]c"] = {
			function()
				if vim.wo.diff then
					return "]c"
				end
				vim.schedule(function()
					require("gitsigns").next_hunk()
				end)
				return "<Ignore>"
			end,
			"Jump to next hunk",
			opts = { expr = true },
		},
		["[c"] = {
			function()
				if vim.wo.diff then
					return "[c"
				end
				vim.schedule(function()
					require("gitsigns").prev_hunk()
				end)
				return "<Ignore>"
			end,
			"Jump to prev hunk",
			opts = { expr = true },
		},
		-- Actions
		["<leader>rh"] = {
			function()
				require("gitsigns").reset_hunk()
			end,
			"Reset hunk",
		},
		["<leader>ph"] = {
			function()
				require("gitsigns").preview_hunk()
			end,
			"Preview hunk",
		},
		["<leader>gb"] = {
			function()
				package.loaded.gitsigns.blame_line()
			end,
			"Blame line",
		},
		["<leader>td"] = {
			function()
				require("gitsigns").toggle_deleted()
			end,
			"Toggle deleted",
		},
	},
}

-- autosave
require("auto-save").setup({
	enabled = true, -- start auto-save when the plugin is loaded (i.e. when your package manager loads it)
	execution_message = {
		message = function() -- message to print on save
			return ("AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"))
		end,
		dim = 0.18, -- dim the color of `message`
		cleaning_interval = 1250, -- (milliseconds) automatically clean MsgArea after displaying `message`. See :h MsgArea
	},
	trigger_events = { "InsertLeave", "TextChanged" }, -- vim events that trigger auto-save. See :h events
	-- function that determines whether to save the current buffer or not
	-- return true: if buffer is ok to be saved
	-- return false: if it's not ok to be saved
	condition = function(buf)
		local fn = vim.fn
		local utils = require("auto-save.utils.data")

		if fn.getbufvar(buf, "&modifiable") == 1 and utils.not_in(fn.getbufvar(buf, "&filetype"), {}) then
			return true -- met condition(s), can save
		end
		return false -- can't save
	end,
	write_all_buffers = false, -- write all buffers when the current one meets `condition`
	debounce_delay = 135, -- saves the file at most every `debounce_delay` milliseconds
	callbacks = {
		-- functions to be executed at different intervals
		enabling = nil, -- ran when enabling auto-save
		disabling = nil, -- ran when disabling auto-save
		before_asserting_save = nil, -- ran before checking `condition`
		before_saving = nil, -- ran before doing the actual save
		after_saving = nil, -- ran after doing the actual save
	},
})

function LEAP_JUMP()
	local focusable_windows_on_tabpage = vim.tbl_filter(function(win)
		return vim.api.nvim_win_get_config(win).focusable
	end, vim.api.nvim_tabpage_list_wins(0))
	require("leap").leap({ target_windows = focusable_windows_on_tabpage })
end

-- leap
M.leap = {
	n = {
		["F"] = { "<CMD>lua LEAP_JUMP()<CR>", "leap jump" },
	},
}

-- lsp
require("core.lsp")
vim.diagnostic.config({
	virtual_text = true,
	signs = true,
	-- 在输入模式下也更新提示，设置为 true 也许会影响性能
	update_in_insert = false,
})

M.lsp = {
	n = {
		["<leader>/"] = { "<CMD>lua require('Comment.api').toggle.linewise.current()<CR>", "toggle comment" },
		["<leader>s"] = { "<cmd>Lspsaga code_action<CR>", "code action" },
		["<LEADER>fm"] = { "<CMD>lua vim.lsp.buf.format { async = true } <CR>", "lsp formatting" },
		["<LEADER>o"] = { "<CMD>SymbolsOutline<CR>", "lsp outline" },
		["gd"] = { "<CMD>lua vim.lsp.buf.definition()<CR>", "lsp goto definition" },
		["gD"] = { "<CMD>lua vim.lsp.buf.declaration()<CR>", "lsp goto declaration" },
		["gi"] = { "<CMD>lua require('telescope.builtin').lsp_implementations()<CR>", "lsp implementations" },
		["gh"] = { "<CMD>Lspsaga hover_doc<CR>", "lsp hover" },
		["gr"] = { "<CMD>lua require('telescope.builtin').lsp_references()<CR>", "lsp references" },
		["go"] = { "<CMD>lua require('telescope.builtin').lsp_outgoing_calls()<CR>", "lsp outgoing_calls" },
		["gk"] = { "<cmd>lua vim.diagnostic.goto_prev()<CR>", "next problem" },
		["gj"] = { "<cmd>lua vim.diagnostic.goto_next()<CR>", "pre problem" },
		-- ["<LEADER>hh"] = {
		-- 	"<CMD>lua vim.lsp.buf.clear_references()<CR><CMD>lua vim.lsp.buf.document_highlight()<CR>",
		-- 	"lsp highlight value",
		-- },
		-- ["<LEADER>ch"] = { "<CMD>lua vim.lsp.buf.clear_references()<CR>", "lsp clear highlight" },
		["<LEADER>rn"] = { "<CMD>Lspsaga rename<CR>", "lsp rename" },
		["<LEADER>["] = { "zc", "folding" },
		["<LEADER>]"] = { "zx", "expansion" },
		["<LEADER>tb"] = { "<CMD>Trouble document_diagnostics<CR>", "document diagnostics" },
	},
	v = {
		["<leader>/"] = {
			"<ESC><cmd>lua require('Comment.api').toggle.linewise(vim.fn.visualmode())<CR>",
			"toggle comment",
		},
		["<leader>s"] = { "<cmd>Lspsaga code_action<CR>", "code action" },
	},
	o = {
		{ "<CMD>LspInfo<CR>", "lsp info" },
		{ "<CMD>LspRestart<CR>", "lsp restart" },
		{ "<CMD>LspLog<CR>", "lsp log" },
	},
}

M.dap = {}

-- 补全
require("core.custom.cmp-config")

-- terminal
require("toggleterm").setup({})
local Terminal = require("toggleterm.terminal").Terminal
local lazygit = Terminal:new({
	cmd = "lazygit",
	dir = "git_dir",
	direction = "float",
	float_opts = {
		border = "double",
	},
	-- function to run on opening the terminal
	on_open = function(term)
		vim.cmd("startinsert!")
		vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "<cmd>close<CR>", { noremap = true, silent = true })
	end,
	-- function to run on closing the terminal
	on_close = function(term)
		vim.cmd("startinsert!")
	end,
})

function LAZYGIT_TOGGLE()
	lazygit:toggle()
end

M.terminal = {
	n = {
		["<LEADER>th"] = { "<CMD>ToggleTerm<CR>", "open terminal" },
		["<LEADER>lg"] = { "<CMD>lua LAZYGIT_TOGGLE()<CR>", "lazygit client" },
		["<LEADER>ft"] = { "<CMD>ToggleTerm direction=float<CR>", "float terminal" },
	},
}

-- mini
require("mini.move").setup({
	-- Options which control moving behavior
	mappings = {
		left = "H",
		right = "L",
		down = "J",
		up = "K",
	},
	options = {
		-- Automatically reindent selection during linewise vertical move
		reindent_linewise = true,
	},
})
-- require("mini.map").setup({})
-- require("mini.map").open()

require("tabnine").setup({
	disable_auto_comment = true,
	accept_keymap = "<Tab>",
	dismiss_keymap = "<C-]>",
	debounce_ms = 800,
	suggestion_color = { gui = "#808080", cterm = 244 },
	exclude_filetypes = { "TelescopePrompt" },
})

-- 使用command_center 来注册快捷键
require("core.custom.telescope-command-center").add_command(M)
